package utils

import (
	"bytes"
	"encoding/base64"
	"encoding/gob"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"hash/fnv"
	"io/ioutil"
	"math"
	"math/rand"
	"net/http"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	"gitee.com/sansaniot/ssiot-core/config"
	"gitee.com/sansaniot/ssiot-core/logger"
	"github.com/bytedance/sonic"
	"github.com/dgrijalva/jwt-go"
	jsoniter "github.com/json-iterator/go"
	uuid "github.com/satori/go.uuid"
	"gorm.io/datatypes"

	"ssalarm/common/constant"
)

// 生成简单uuid
func SimpleUUID() string {
	return strings.ReplaceAll(uuid.NewV4().String(), "-", "")
}

// 生成随机编码、变量名
func GenUniqueName(wantMillis ...int64) string {
	timeInMillis := time.Now().UnixMilli()
	if len(wantMillis) > 0 {
		timeInMillis = wantMillis[0]
	}
	str := strconv.FormatInt(timeInMillis, 10)
	s := base64.StdEncoding.EncodeToString([]byte(str))
	return strings.ToLower(strings.ReplaceAll(s, "=", ""))
}

// 判断字符串数组存在
func StrIn(target string, strArray []string) bool {
	sort.Strings(strArray)
	index := sort.SearchStrings(strArray, target)
	if index < len(strArray) && strArray[index] == target {
		return true
	}
	return false
}

// 判断整型数组存在
func IntIn(target int, intArray []int) bool {
	sort.Ints(intArray)
	index := sort.SearchInts(intArray, target)
	if index < len(intArray) && intArray[index] == target {
		return true
	}
	return false
}

// 深度拷贝(gob序列化方式)
func GobDeepCopy(src, dst interface{}) error {
	var buffer bytes.Buffer
	if err := gob.NewEncoder(&buffer).Encode(src); err != nil {
		return err
	}
	return gob.NewDecoder(&buffer).Decode(dst)
}

// 三目运算?
func If(flag bool, a, b interface{}) interface{} {
	if flag {
		return a
	}
	return b
}

// map融合
func MapGather(map1, map2 map[string]string) map[string]string {
	if (map1 == nil || len(map1) == 0) && (map2 == nil || len(map2) == 0) {
		return make(map[string]string)
	}
	if map1 == nil || len(map1) == 0 {
		return map2
	}
	if map2 == nil || len(map2) == 0 {
		return map1
	}
	for _, _ = range map1 {
		for k2, _ := range map2 {
			map1[k2] = map2[k2]
		}
	}
	return map1
}
func MapGather2(map1, map2 map[string]interface{}) map[string]interface{} {
	if (map1 == nil || len(map1) == 0) && (map2 == nil || len(map2) == 0) {
		return make(map[string]interface{})
	}
	if map1 == nil || len(map1) == 0 {
		return map2
	}
	if map2 == nil || len(map2) == 0 {
		return map1
	}
	for _, _ = range map1 {
		for k2, _ := range map2 {
			map1[k2] = map2[k2]
		}
	}
	return map1
}

// 数组最大值
func FindMaxElement(arr []int) int {
	maxNum := arr[0]
	for i := 0; i < len(arr); i++ {
		if arr[i] > maxNum {
			maxNum = arr[i]
		}
	}
	return maxNum
}

// 字符串都为空
func StringAllEmpty(ss ...string) bool {
	flag := true
	for _, str := range ss {
		if len(str) > 0 {
			flag = false
			break
		}
	}
	return flag
}

// 字符串存在空
func StringAnyEmpty(ss ...string) bool {
	flag := false
	for _, str := range ss {
		if len(str) == 0 {
			flag = true
			break
		}
	}
	return flag
}

// 提取接口参数addr
func GetParamAddr(param interface{}) (addr string) {
	addr = ""
	if param == nil {
		return
	}
	var paramObj map[string]interface{}
	if obj, ok := param.(map[string]interface{}); ok {
		paramObj = obj
	} else if obj, ok := param.(datatypes.JSON); ok {
		paramObj = BytesToMap(obj)
	}
	if v, ok := paramObj["addr"]; ok && v != nil {
		addr = v.(string)
	}
	return
}

func MapToBytes(m map[string]interface{}) []byte {
	if m == nil {
		return []byte{}
	}
	mBytes, _ := sonic.Marshal(m)
	return mBytes
}

func MapArrToBytes(m []map[string]interface{}) []byte {
	if m == nil {
		return []byte{}
	}
	mBytes, _ := sonic.Marshal(m)
	return mBytes
}

func BytesToMap(b []byte) map[string]interface{} {
	var m = make(map[string]interface{})
	if b == nil {
		return m
	}
	_ = sonic.Unmarshal(b, &m)
	return m
}

func BytesToMapArr(b []byte) []map[string]interface{} {
	var m = make([]map[string]interface{}, 0)
	if b == nil {
		return m
	}
	_ = sonic.Unmarshal(b, &m)
	return m
}

// 差集
func RemoveAll(remover *[]string, removeBy []string) (flag bool) {
	flag = false
	for _, str := range removeBy {
		for i := len(*remover) - 1; i >= 0; i-- {
			if (*remover)[i] == str {
				*remover = append((*remover)[:i], (*remover)[i+1:]...)
				flag = true
				break
			}
		}
	}
	return
}

const SnPrefix = "SN"

// 随机生成sn(18位)
func GenRandomSn() string {
	snSuffix := ""
	for i := 1; i <= 16; i++ {
		snSuffix += strconv.Itoa(rand.Intn(10))
	}
	return SnPrefix + snSuffix
}

// 间隔天数
func DiffDays(format, time1, time2 string) (int, error) {
	date1, err := time.ParseInLocation(format, time1, time.Local)
	if err != nil {
		return 0, err
	}
	date2, err := time.ParseInLocation(format, time2, time.Local)
	if err != nil {
		return 0, err
	}
	return int(math.Abs(date1.Sub(date2).Hours() / 24)), nil
}

// 转发为map
func sliceToMap(userStationId []string) map[string]interface{} {
	//结果
	mapResult := make(map[string]interface{})
	//获取所有在线设备
	for _, value := range userStationId {
		//缓存
		mapResult[value] = 1
	}
	//返回
	return mapResult
}

// 获取map集合的key
func KeySet(jsonData map[string]interface{}) []string {
	keys := make([]string, len(jsonData))
	j := 0
	for key, _ := range jsonData {
		keys[j] = key
		j++
	}
	return keys
}

// 类型转化
func GetMapValueFiled(jsonData map[string]interface{}, field string) map[string]interface{} {
	if jsonData[field] == nil {
		return nil
	}
	dataMap, ok := jsonData[field].(map[string]interface{})
	if !ok {
		return nil
	}
	return dataMap
}

// 类型转化
func GetStringValueFiled(jsonData map[string]interface{}, field string) string {
	if jsonData == nil {
		return ""
	}
	//判断是否存在
	if value, ok := jsonData[field]; ok {
		//判断是否正确
		if stringValue, ok := value.(string); ok {
			return stringValue
		} else if interfaceVal, ok := value.(interface{}); ok {
			//格式转化
			valStr := InterfaceToStr(interfaceVal)
			//判断是否正确
			return valStr
		} else if timeVal, ok := value.(time.Time); ok {
			//格式转化
			valStr := FormatTimeToStr(timeVal)
			//判断是否正确
			return valStr
		} else {
			return ""
		}
	} else {
		return ""
	}
}

func GetIntValueFiled(jsonData map[string]interface{}, field string) int {
	if jsonData == nil {
		return 0
	}
	//判断是否存在
	if value, ok := jsonData[field]; ok && value != nil {
		//判断是否是bool类型
		intValue, ok := value.(int)
		//判断是否正确
		if ok {
			return intValue
		} else if stringValue, ok := value.(string); ok {
			//格式转化
			valueIntString, err := strconv.Atoi(stringValue)
			//判断是否正确
			if err == nil {
				return valueIntString
			} else {
				return 0
			}
		} else if floatValue, ok := value.(float64); ok {
			//格式转化
			return int(floatValue)
		} else {
			return 0
		}
	} else {
		return 0
	}
}

func GetBoolValueField(jsonData map[string]interface{}, field string) bool {
	if jsonData == nil {
		return false
	}
	//判断是否存在
	if value, ok := jsonData[field]; ok && value != nil {
		//判断是否是bool类型
		boolValue, ok := value.(bool)
		//判断是否正确
		if ok {
			return boolValue
		} else {
			return false
		}
	} else {
		return false
	}
}

// 类型转化
func FormatMapSliceToStrSlice(jsonData []map[string]interface{}, field string) []string {
	//结果
	resultList := make([]string, 0)
	//遍历处理
	for _, devItem := range jsonData {
		//处理和缓存
		fieldVal := GetStringValueFiled(devItem, field)
		//有效存在
		if fieldVal != "" {
			resultList = append(resultList, fieldVal)
		}
	}
	return resultList
}

// 类型转化
func FormatMapSliceToMap(jsonData []map[string]interface{}, field string) map[string]map[string]interface{} {
	//结果
	resultMap := make(map[string]map[string]interface{})
	//遍历处理
	for _, devItem := range jsonData {
		//处理和缓存
		fieldVal := GetStringValueFiled(devItem, field)
		//有效存在
		resultMap[fieldVal] = devItem
	}
	return resultMap
}

// 类型转化
func GetFloatValueFiled(jsonData map[string]interface{}, field string) float64 {
	if jsonData == nil {
		return 0
	}
	//判断是否存在
	if value, ok := jsonData[field]; ok && value != nil {
		//数据处理
		return FormatFloatValue(value)
	} else {
		return 0.0
	}
}

// 类型转化
func GetFloat32ValueFiled(jsonData map[string]interface{}, field string) float32 {
	if jsonData == nil {
		return 0
	}
	//判断是否存在
	if value, ok := jsonData[field]; ok {
		//获取结果
		float64Val := FormatFloatValue(value)
		//数据处理
		return float32(float64Val)
	} else {
		return 0.0
	}
}

// 类型转化
func FormatFloatValue(floatValue interface{}) float64 {
	//值
	formatValue, ok := floatValue.(float64)
	//判断是否正确
	if ok {
		return formatValue
	} else if stringValue, ok := floatValue.(string); ok {
		//格式转化
		valueIntString, err := strconv.ParseFloat(stringValue, 64)
		//判断是否正确
		if err == nil {
			return valueIntString
		} else {
			return 0.0
		}
	} else {
		return 0.0
	}
}

// 字符串切割处理
func SplitReturnToIntSlice(source string, splitStr string) []int {
	//判断是否存在
	intSlice := make([]int, 0)
	//得到结果
	listResult := strings.Split(source, splitStr)
	//遍历去掉空格
	for index, _ := range listResult {
		//去掉空格
		formatValue := strings.Trim(listResult[index], " ")
		//转化int
		formatIntValue, _ := strconv.Atoi(formatValue)
		//缓存
		intSlice = append(intSlice, formatIntValue)
	}
	//返回
	return intSlice
}

// 字符串切割处理
func SplitReturnToSlice(source string, splitStr string) []string {
	//判断是否存在
	strSlice := make([]string, 0)
	//得到结果
	listResult := strings.Split(source, splitStr)
	//遍历去掉空格
	for index, _ := range listResult {
		//去掉空格
		formatValue := strings.Trim(listResult[index], " ")
		//缓存
		if len(formatValue) > 0 {
			strSlice = append(strSlice, formatValue)
		}
	}
	//返回
	return strSlice
}

// 时间戳格式处理
func FormatTimestampStr(timestamp string) string {
	//转化为int64
	timestampVal, err := strconv.ParseInt(timestamp, 10, 64)
	//判断是否有错误
	if err != nil {
		return ""
	}
	//转化为time格式
	timeNow := time.UnixMilli(timestampVal) //2017-08-30 16:19:19 +0800 CST
	//格式处理
	return formatDate(timeNow, "yyyy-MM-dd HH:mm:ss")
}

// 格式处理
func FormatMapToArray(jsonData map[string]map[string]interface{}) []map[string]interface{} {
	//判断是否存在
	sliceMap := make([]map[string]interface{}, 0)
	//遍历
	for _, item := range jsonData {
		sliceMap = append(sliceMap, item)
	}
	return sliceMap
}

// 获取当前时间戳
func GetNowTimestampStr() string {
	//ms级别
	return Int64ToStr(time.Now().UnixNano() / 1e6)
}

func Int64ToStr(value int64) string {
	return strconv.FormatInt(value, 10)
}

func GetNowTimeStr() string {
	return formatDate(time.Now(), "yyyy-MM-dd HH:mm:ss")
}

func GetNowTimeStr2() string {
	return formatDate(time.Now(), "yyyy_MM_dd_HH_mm_ss")
}

// 时间格式处理
func FormatTimeToStr(timeVal time.Time) string {
	//格式处理
	return formatDate(timeVal, "yyyy-MM-dd HH:mm:ss")
}

// 时间格式处理
func FormatStrTime(strTime string) (time.Time, error) {
	//处理
	loc, _ := time.LoadLocation("Local")
	//时间格式处理
	formatTime, err := time.ParseInLocation("2006-01-02 15:04:05", strTime, loc)
	//返回
	return formatTime, err
}

func FormatStrTimePoint(strTime string) *time.Time {
	//处理
	formatTime, err := FormatStrTime(strTime)
	//处理
	if err != nil {
		return nil
	} else {
		return &formatTime
	}
}

// 秒数格式化时长
func SecondToTimeDuration(seconds int) string {
	duration := ""
	//second := seconds % 60
	minute := seconds % 3600 / 60
	hour := seconds % (24 * 3600) / 3600
	day := seconds / (24 * 3600)
	if day > 0 {
		duration += strconv.Itoa(day) + "天"
	}
	if hour > 0 {
		duration += strconv.Itoa(hour) + "时"
	}
	if minute > 0 {
		duration += strconv.Itoa(minute) + "分"
	}
	return duration
}

// 获取当前时间
func GetStrPoint(str string) *string {
	return &str
}

// 处理大小写转化的问题
func FormatLower(value string, list []string) string {
	//格式处理
	for _, val := range list {
		//比较
		if strings.EqualFold(value, val) {
			return val
		}
	}
	return value
}

func formatDate(date time.Time, layout string) string {
	layout = strings.Replace(layout, "yyyy", "2006", 1)
	layout = strings.Replace(layout, "yy", "06", 1)
	layout = strings.Replace(layout, "MM", "01", 1)
	layout = strings.Replace(layout, "dd", "02", 1)
	layout = strings.Replace(layout, "HH", "15", 1)
	layout = strings.Replace(layout, "mm", "04", 1)
	layout = strings.Replace(layout, "ss", "05", 1)
	layout = strings.Replace(layout, "SSS", "000", -1)
	return date.Format(layout)
}

func copyMap(m map[string]interface{}) map[string]interface{} {
	cp := make(map[string]interface{})
	for k, v := range m {
		vm, ok := v.(map[string]interface{})
		if ok {
			cp[k] = copyMap(vm)
		} else {
			cp[k] = v
		}
	}
	return cp
}

func FixJsonKeyDot(obj map[string]interface{}) map[string]interface{} {
	if obj == nil {
		return make(map[string]interface{})
	}
	tmp := copyMap(obj)
	for key, value := range obj {
		if !strings.Contains(key, ".") {
			continue
		}
		delete(tmp, key)
		s := strings.Split(key, ".")
		i := 0
		if _, ok := tmp[s[i]]; !ok {
			tmp[s[i]] = make(map[string]interface{})
		}
		for i+1 <= len(s)-1 {
			i++
			j := 0
			jsonObj := tmp[s[j]].(map[string]interface{})
			for ; j < i-1; j++ {
				jsonObj = jsonObj[s[j+1]].(map[string]interface{})
			}
			if i < len(s)-1 {
				if _, ok := jsonObj[s[i]]; !ok {
					jsonObj[s[i]] = make(map[string]interface{})
				}
			} else {
				jsonObj[s[i]] = value
			}
		}
	}
	return tmp
}

func DeepMerge(source, target map[string]interface{}) {
	for key, value := range source {
		if _, ok := target[key]; !ok {
			target[key] = source[key]
		} else {
			if valueJson, ok := value.(map[string]interface{}); ok {
				if _, ok2 := target[key].(map[string]interface{}); ok2 {
					DeepMerge(valueJson, target[key].(map[string]interface{}))
				} else {
					// 字段类型变了
					target[key] = source[key]
				}
			} else {
				target[key] = source[key]
			}
		}
	}
}

func InterfaceToStr(value interface{}) string {
	var key string
	if value == nil {
		return key
	}
	switch value.(type) {
	case float64:
		ft := value.(float64)
		key = strconv.FormatFloat(ft, 'f', -1, 64)
	case float32:
		ft := value.(float32)
		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
	case int:
		it := value.(int)
		key = strconv.Itoa(it)
	case uint:
		it := value.(uint)
		key = strconv.Itoa(int(it))
	case int8:
		it := value.(int8)
		key = strconv.Itoa(int(it))
	case uint8:
		it := value.(uint8)
		key = strconv.Itoa(int(it))
	case int16:
		it := value.(int16)
		key = strconv.Itoa(int(it))
	case uint16:
		it := value.(uint16)
		key = strconv.Itoa(int(it))
	case int32:
		it := value.(int32)
		key = strconv.Itoa(int(it))
	case uint32:
		it := value.(uint32)
		key = strconv.Itoa(int(it))
	case int64:
		it := value.(int64)
		key = strconv.FormatInt(it, 10)
	case uint64:
		it := value.(uint64)
		key = strconv.FormatUint(it, 10)
	case string:
		key = value.(string)
	case []byte:
		key = string(value.([]byte))
	case *int:
		var val = value.(*int)
		key = strconv.Itoa(*val)
	case *string:
		var val = value.(*string)
		key = *val
	default:
		key, _ = sonic.MarshalString(value)
	}
	return key
}

func String2IntArr(value string) []int {
	a := make([]int, 0)
	for _, v := range []byte(value) {
		a = append(a, int(v))
	}
	return a
}

func HexStr2IntArr(value string) []int {
	value = strings.ReplaceAll(value, " ", "")
	a := make([]int, 0)
	bs, err := hex.DecodeString(value)
	if err != nil {
		return a
	}
	return String2IntArr(string(bs))
}

func FloatArr2String(a []float64) string {
	s := ""
	for _, v := range a {
		s += string(byte(v))
	}
	return s
}

// 统一格式处理历史设备属性表名称
func FormatHistoryTable(sn string, key string) string {
	//表
	tb := ""
	//判断
	if key == "" {
		tb = fmt.Sprintf("z_%s", sn)
	} else {
		tb = fmt.Sprintf("z_%s_%s", sn, key)
	}
	//统一小写处理
	tb = strings.ToLower(tb)
	//返回
	return tb
}

// 历史属性表名称特殊处理(sn不允许下划线)
func FormatHistoryTableSn(tableName string) string {
	//切割处理
	listResult := SplitReturnToSlice(tableName, "_")
	//最后一个必定为key
	devSn := listResult[1]
	//返回
	return strings.ToUpper(devSn)
}

func FormatHistoryTableKey(tableName string) string {
	//切割处理
	listResult := SplitReturnToSlice(tableName, "_")
	//排除第一个z和sn  z_sn5207973436305017_ab_cd
	formatList := listResult[2:]
	//属性key
	valKey := strings.Join(formatList, "_")
	//返回
	return strings.ToLower(valKey)
}

// 字符串时间标记大小
func CompareMaxStrTime(time1 string, time2 string) string {
	//先把时间字符串格式化成相同的时间类型
	t1, err1 := time.Parse("2006-01-02 15:04:05", time1)
	//有效判断
	if err1 != nil {
		return time2
	}
	t2, err2 := time.Parse("2006-01-02 15:04:05", time2)
	//有效判断
	if err2 != nil {
		return time1
	}
	//处理
	if t1.After(t2) {
		return time1
	} else {
		return time2
	}
}

var client = http.Client{
	Timeout: 10 * time.Second,
}

func HttpGetJson(url string, param map[string]string, header map[string]string, result interface{}) error {
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return err
	}
	q := req.URL.Query()
	if param != nil {
		for k, v := range param {
			q.Add(k, v)
		}
	}
	if header != nil {
		for k, v := range header {
			req.Header.Add(k, v)
		}
	}
	req.URL.RawQuery = q.Encode()
	logger.Infof("HTTP Get请求：%s, %s", url, req.URL.RawQuery)
	response, err := client.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}
	err = sonic.Unmarshal(body, &result)
	if err != nil {
		return err
	}
	return nil
}

func HttpPostJson(url string, param map[string]interface{}, header map[string]string, result interface{}) error {
	buf := bytes.NewBuffer(nil)
	encoder := json.NewEncoder(buf)
	if err := encoder.Encode(param); err != nil {
		return err
	}
	request, err := http.NewRequest(http.MethodPost, url, buf)
	if err != nil {
		return err
	}
	request.Header.Add("Content-Type", "application/json")
	if header != nil {
		for k, v := range header {
			request.Header.Add(k, v)
		}
	}
	logger.Infof("HTTP Post请求：%s, %s", url, buf.String())
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}
	err = sonic.Unmarshal(body, &result)
	if err != nil {
		return err
	}
	return nil
}

// 比较两个json内容是否一致
func IsJsonEqual(map1, map2 map[string]interface{}) bool {
	map1Str := string(MapToBytes(map1))
	map2Str := string(MapToBytes(map2))
	rune1 := []rune(strings.ReplaceAll(map1Str, " ", ""))
	rune2 := []rune(strings.ReplaceAll(map2Str, " ", ""))
	sort.Slice(rune1, func(i, j int) bool {
		return rune1[i] < rune1[j] // 正序
	})
	sort.Slice(rune2, func(i, j int) bool {
		return rune2[i] < rune2[j] // 正序
	})
	return string(rune1) == string(rune2)
}

var phoneMatcher = regexp.MustCompile("^1[3-9]\\d{9}$")

// 手机号校验
func CheckMobile(phone string) bool {
	return phoneMatcher.MatchString(phone)
}

// 驼峰单词转下划线单词
func CamelCaseToUdnderscore(s string) string {
	var output []rune
	for i, r := range s {
		if i == 0 {
			output = append(output, unicode.ToLower(r))
		} else {
			if unicode.IsUpper(r) {
				output = append(output, '_')
			}

			output = append(output, unicode.ToLower(r))
		}
	}
	return string(output)
}

// 获取json指定路径值
func GetFieldFromJson(path []string, jsonObj map[string]interface{}) interface{} {
	value, err := jsoniter.Marshal(jsonObj)
	if err != nil {
		return nil
	}
	var temp jsoniter.Any
	for i, v := range path {
		if i == 0 {
			temp = jsoniter.Get(value, v)
			if temp == nil {
				return nil
			}
		} else {
			if temp == nil {
				return nil
			}
			temp = temp.Get(v)
			if temp == nil {
				return nil
			}
		}
	}
	if temp == nil {
		return nil
	}
	switch temp.ValueType() {
	case jsoniter.InvalidValue, jsoniter.NilValue:
		return nil
	case jsoniter.ObjectValue:
		jsonByte, _ := jsoniter.Marshal(temp)
		return BytesToMap(jsonByte)
	default:
		return temp.GetInterface()
	}
}

func JsoniterToMap(v interface{}) map[string]interface{} {
	jsonByte, _ := jsoniter.Marshal(v)
	jsonMap := make(map[string]interface{})
	//数据转换
	_ = jsoniter.Unmarshal(jsonByte, &jsonMap)
	//解析成功
	return jsonMap
}

func GetFieldFromJsonByte(path []string, jsonByte []byte) []byte {
	schemaJson := BytesToMap(jsonByte)
	value := GetFieldFromJson(path, schemaJson)
	bytes, _ := jsoniter.Marshal(value)
	return bytes
}

// 获取schema描述(平台业务)
func GetObjectSchema(obj interface{}) (jsonSchema map[string]interface{}) {
	typeOf := getTypeof(obj)
	jsonSchema = map[string]interface{}{
		"type": typeOf,
	}
	if typeOf == "object" {
		jsonSchema["required"] = BytesToMapArr(nil)
		tmp := map[string]interface{}{}
		for kk, vv := range obj.(map[string]interface{}) {
			tmp[kk] = GetObjectSchema(vv)
		}
		jsonSchema["properties"] = tmp
	} else if typeOf == "array" {
		jsonSchema["required"] = BytesToMapArr(nil)
		arr := obj.([]interface{})
		if len(arr) == 0 {
			jsonSchema["items"] = map[string]interface{}{
				"type": "string",
			}
		} else {
			jsonSchema["items"] = GetObjectSchema(arr[0])
		}
	}
	return
}

func getTypeof(v interface{}) string {
	typeOf := fmt.Sprintf("%T", v)
	// 注意if顺序
	if strings.Contains(typeOf, "[]") {
		typeOf = "array"
	} else if strings.Contains(typeOf, "map[string]interface") {
		typeOf = "object"
	} else if strings.Contains(typeOf, "string") {
		typeOf = "string"
	} else if strings.Contains(typeOf, "nil") {
		//typeOf = "nil"
		typeOf = ""
	} else if strings.Contains(typeOf, "bool") {
		typeOf = "boolean"
	} else {
		typeOf = "number"
	}
	return typeOf
}

func GetObjectConfig(obj interface{}) (jsonConfig map[string]interface{}) {
	typeOf := getTypeof(obj)
	jsonConfig = map[string]interface{}{}
	if typeOf == "object" {
		for kk, vv := range obj.(map[string]interface{}) {
			jsonConfig[kk] = GetObjectConfig(vv)
		}
	}
	return
}

func IsJsonOrArray(str string) bool {
	str = strings.TrimSpace(str)
	return (strings.HasPrefix(str, "{") && strings.HasSuffix(str, "}")) ||
		(strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]"))
}

func GenServerToken() (tokenString string) {
	token := jwt.New(jwt.GetSigningMethod("HS256"))
	claims := token.Claims.(jwt.MapClaims)
	// 微服务管理负载内容
	claims[constant.JwtKeyUserName] = "sansaniot"
	expire := time.Now().Add(10 * time.Minute)
	claims["exp"] = expire.Unix()
	claims["orig_iat"] = time.Now().Unix()
	tokenString, _ = token.SignedString([]byte(config.JwtConfig.Secret))
	return
}

// json层级拉平成k.kk形式
func FlattenJson(source, flatten map[string]interface{}, ignore []string) {
	for k, v := range source {
		if StrIn(k, ignore) {
			continue
		}
		switch v.(type) {
		case map[string]interface{}:
			for kk, v := range v.(map[string]interface{}) {
				flatten[k+"."+kk] = v
			}
			ignore = append(ignore, k)
			FlattenJson(flatten, flatten, ignore)
		default:
			flatten[k] = v
		}
	}
	for _, v := range ignore {
		delete(flatten, v)
	}
}
func HashVal(s string) int {
	hash := fnv.New32a()
	_, _ = hash.Write([]byte(s))
	return int(hash.Sum32())
}

func GetStringProtoInterface(s string) interface{} {
	if float64Val, err := strconv.ParseFloat(s, 64); err == nil {
		return float64Val
	} else if strings.Contains(s, "[") && strings.Contains(s, "]") {
		if strings.Contains(s, "{") && strings.Contains(s, "}") {
			m := make([]map[string]interface{}, 0)
			if err = sonic.Unmarshal([]byte(s), &m); err == nil {
				return m
			}
		} else {
			s = strings.Replace(s, "[", "", 1)
			s = strings.Replace(s, "]", "", 1)
			return strings.Split(s, ",")
		}
	} else if strings.Contains(s, "{") && strings.Contains(s, "}") {
		m := make(map[string]interface{})
		if err = sonic.Unmarshal([]byte(s), &m); err == nil {
			return m
		}
	}
	return s
}

func FlattenJsonWithRoot(source, flatten map[string]interface{}, ignore []string, root map[string]interface{}) {
	for k, v := range source {
		if StrIn(k, ignore) {
			continue
		}
		switch v.(type) {
		case map[string]interface{}:
			for kk, v := range v.(map[string]interface{}) {
				flatten[k+"."+kk] = v
			}
			root[k] = v
			ignore = append(ignore, k)
			FlattenJsonWithRoot(flatten, flatten, ignore, root)
		default:
			flatten[k] = v
		}
	}
	for _, v := range ignore {
		delete(flatten, v)
	}
	DeepMerge(root, flatten)
}

type mySlice interface {
	int | int8 | int16 | int64 | float32 | float64 | string | byte
}

func InsertIntoSlice[T mySlice](slice []T, index int, element T) []T {
	if index >= len(slice) {
		return slice
	}

	// 创建一个新的切片，长度比原切片多1
	newSlice := make([]T, len(slice)+1)

	// 复制元素到新切片
	copy(newSlice, slice[:index])
	newSlice[index] = element
	copy(newSlice[index+1:], slice[index:])

	// 使用新切片替换原切片
	return newSlice
}
